Skip to content

feat(auth): migrate auth APIs to AmplifyContext - #14836

Merged
bobbor merged 11 commits into
feat/bobbor/v6-contextfrom
feat/b-auth-context
Jul 7, 2026
Merged

feat(auth): migrate auth APIs to AmplifyContext#14836
bobbor merged 11 commits into
feat/bobbor/v6-contextfrom
feat/b-auth-context

Conversation

@bobbor

@bobbor bobbor commented Jun 2, 2026

Copy link
Copy Markdown
Member

Summary

Migrates all auth package APIs from the legacy Amplify singleton pattern to the new AmplifyContext interface.

Changes

Public APIs (26 files)

All exported auth functions now have overloads:

  • fn(input) — uses getGlobalContext() fallback (browser/client usage)
  • fn(ctx, input) — explicit context (server or multi-context usage)

Uses resolveCtxArgs from core to resolve the optional leading context argument.

Server wrappers (2 files)

  • server/getCurrentUser.ts and server/fetchUserAttributes.ts take AmplifyContext explicitly
  • No global fallback — signals Node.js/per-request context requirement
  • Preserves the server/ entry point structure (like storage package)

Internal functions (5 signIn variants + utilities)

  • signInWithSRP, signInWithUserPassword, etc. take (ctx, input) directly
  • assertUserNotAuthenticated(ctx), dispatchSignedInHubEvent(ctx)

Foundation changes

  • AmplifyClassV6AmplifyContext
  • amplify.getConfig()amplify.resourcesConfig
  • amplify.Auth.getTokens()amplify.getTokens()

Tests

  • Added createMockAmplifyContext() test utility
  • Updated 6 test files to use mock context

What was tested

  • TypeScript compilation passes (no source-level errors from this change)
  • All TS2554 (argument count) errors in tests resolved

- Add AmplifyContext overloads to all public auth APIs (signIn, signUp,
  signOut, getCurrentUser, fetchUserAttributes, confirmSignIn, etc.)
- Public APIs use resolveCtxArgs with getGlobalContext() fallback
- Server wrappers (server/getCurrentUser, server/fetchUserAttributes)
  take AmplifyContext explicitly — no global fallback
- Internal signIn variants take (ctx, input) directly
- Utilities (assertUserNotAuthenticated, dispatchSignedInHubEvent) accept ctx
- Replace Amplify.getConfig() with ctx.resourcesConfig throughout
- Replace AmplifyClassV6 with AmplifyContext in internal APIs
- Add createMockAmplifyContext test utility
- Update affected test files to use mock context
@changeset-bot

changeset-bot Bot commented Jun 2, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 0c91982

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@bobbor bobbor changed the title feat(auth): migrate auth APIs to AmplifyContext (B-auth) feat(auth): migrate auth APIs to AmplifyContext Jun 2, 2026
bobbor added 6 commits June 2, 2026 14:23
resolveCtxArgs generic constraint requires T extends unknown[].
undefined does not satisfy this - use empty tuple [] instead.
The fetchAuthSession helper from core/internals/utils expects AmplifyClass,
not AmplifyContext. Use the context's own fetchAuthSession method directly.
Maintain backward compatibility with adapter-nextjs which still uses
runWithAmplifyServerContext + ContextSpec pattern. Server wrappers now
detect whether they received an AmplifyContext or ContextSpec and
resolve accordingly.
- Remove unused Amplify imports from test files
- Fix prettier formatting (line length, indentation)
Migrate test mocking from Amplify.getConfig() singleton to passing
mockCtx directly via createMockAmplifyContext(). This aligns tests
with the new resolveCtxArgs pattern where APIs accept an optional
AmplifyContext as their first argument.

- Remove jest.mock('@aws-amplify/core') in favor of direct ctx passing
- Replace fetchAuthSession singleton mock with ctx.fetchAuthSession
- Use customCtx for endpoint override tests
- Fix autoSignInUserConfirmed to match updated signUpHelpers routing
- Add Amplify.configure() for tests that reach getSignInResult (still
  uses singleton internally)
export const getCurrentUser = async (
contextSpec: AmplifyServer.ContextSpec,
export const getCurrentUser = (
ctxOrContextSpec: AmplifyContext | AmplifyServer.ContextSpec,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit / suggestion: This ctxOrContextSpec resolution is duplicated verbatim in both server/fetchUserAttributes.ts and server/getCurrentUser.ts. It'd make a nice small shared utility — something like:

// Resolves a server-side argument that may be either the new AmplifyContext
// or a legacy AmplifyServer.ContextSpec, into a concrete AmplifyContext.
export const resolveServerContext = (
	ctxOrContextSpec: AmplifyContext | AmplifyServer.ContextSpec,
): AmplifyContext =>
	'resourcesConfig' in ctxOrContextSpec
		? ctxOrContextSpec
		: getAmplifyServerContext(ctxOrContextSpec).amplify;

Both call sites then become const ctx = resolveServerContext(ctxOrContextSpec);, and the duck-typing discriminator lives in one place if it ever needs to change.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 9b597bb. Extracted the duck-typing into a shared resolveServerContext helper at apis/server/resolveServerContext.ts:

export const resolveServerContext = (
	ctxOrContextSpec: AmplifyContext | AmplifyServer.ContextSpec,
): AmplifyContext => {
	const ctx =
		'resourcesConfig' in ctxOrContextSpec
			? ctxOrContextSpec
			: getAmplifyServerContext(ctxOrContextSpec).amplify;

	return ctx as AmplifyContext;
};

Both server/getCurrentUser.ts and server/fetchUserAttributes.ts now just call const ctx = resolveServerContext(ctxOrContextSpec);, and the discriminator lives in one place. (Kept the cast inside the helper and dropped the now-redundant call-site casts.)

signInInput?.options?.authFlowType === 'USER_AUTH'
? await signInWithUserAuth(signInInput)
: await signIn(signInInput);
const output = await signIn(signInInput);

@osama-rizk osama-rizk Jun 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please confirm if this change is intended**

This is the one change that isn't a mechanical context migration, and it looks like it may introduce a behavioral regression:

-		const output =
-			signInInput?.options?.authFlowType === 'USER_AUTH'
-				? await signInWithUserAuth(signInInput)
-				: await signIn(signInInput);
+		const output = await signIn(signInInput);

Two things suggest this drops the cached session during USER_AUTH auto sign-in:

  1. Routing through signIn is not equivalent to calling signInWithUserAuth directly — signIn first runs resetAutoSignIn(false) and assertUserNotAuthenticated(ctx). The original code deliberately bypassed those for the USER_AUTH path. Calling them mid-auto-sign-in can disturb the auto-sign-in state machine.
  2. In autoSignIn.test.ts, the assertion that the flow forwards session: 'ASDFGHJKL' was silently removed:
 expect(mockHandleUserAuthFlow).toHaveBeenCalledWith(
 	expect.objectContaining({
 		username: user1.username,
-		session: 'ASDFGHJKL',
 	}),
 );

Dropping a coverage assertion to make a test pass is a red flag. Could you confirm whether the cached session is still threaded into the USER_AUTH flow after this change, or whether this is an unintended regression? If the behavior genuinely changed, it likely deserves its own PR + changelog note rather than an inline assertion deletion.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch — you were right, this was an unintended regression, now fixed in 9b597bb.

Confirmed the cause: routing USER_AUTH through signIn() runs resetAutoSignIn(false) first, which dispatches { type: 'RESET' } to autoSignInStore (the false only preserves the callback, not the store state). By the time signInWithUserAuth runs, its if (autoSignInStoreState.active …) guard is false, so the cached session is never forwarded to handleUserAuthFlow — auto-sign-in starts a fresh flow instead of resuming the primed session.

Restored the branch to call signInWithUserAuth directly (matching v7-poc behavior):

const output =
	signInInput?.options?.authFlowType === 'USER_AUTH'
		? await signInWithUserAuth(getGlobalContext(), signInInput)
		: await signIn(signInInput);

I used getGlobalContext() rather than threading ctx as a parameter because auto-sign-in is inherently client-side/post-configure (consistent with the other client-only flows like completeOAuthFlow and handleWebAuthnSignInResult in this split); the v7-poc ctx-threading can land later without a behavior change.

On the dropped assertion — you were right to flag it. I re-added session: 'ASDFGHJKL' in autoSignIn.test.ts, and I also found autoSignInUserConfirmed.test.ts had been changed to assert the regressed behavior (expecting signIn for USER_AUTH); I corrected it to assert signInWithUserAuth(mockCtx, input) is called and signIn is not. Both tests now pass with the fix (full auth suite green: 101/101 suites, 1144 tests).

const mockReplaceState = jest.fn();

beforeAll(() => {
setGlobalContext(createMockAmplifyContext());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Do we need to call clearGlobalContext() in afterAll here (and in the other test files that call setGlobalContext)?

It looks like only autoSignIn.test.ts cleans up the global context in afterAll. The other files that call setGlobalContext (this one, signInResumable.test.ts, signInWithCustomAuth.test.ts, etc.) leave it set after the suite finishes, which could leak state across files depending on how much module isolation Jest gives us. Should we standardize on a clearGlobalContext() in afterAll for all of them?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — standardized in 9b597bb. Added clearGlobalContext() in afterAll to every suite that calls setGlobalContext (this file, signInResumable, signInWithSRP, signInWithCustomAuth, signInWithCustomSRPAuth, signInWithUserAuth, signInWithUserPassword).

While doing this I found the leak was actually being relied on: in signInWithUserPassword.test.ts the Cognito ASF describe had no context setup of its own and depended on the global context leaking from the sibling signIn API happy path cases describe. Adding cleanup exposed that, so I made Cognito ASF self-contained with its own beforeAll(setGlobalContext) / afterAll(clearGlobalContext).

const ctx: AmplifyContext = {
resourcesConfig,
libraryOptions: {},
fetchAuthSession: jest.fn().mockResolvedValue({}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Could createMockAmplifyContext return the mock members already typed as jest.Mock?

Across the migrated tests, this 3-line incantation recurs ~28× (≈14 for mockCtx and ~14 for the per-test customCtx):

(mockCtx.fetchAuthSession as jest.Mock).mockResolvedValue({
	tokens: { accessToken: decodeJWT(mockAccessToken) },
});

The as jest.Mock cast (28×) exists only because the util types these fields as AmplifyContext['fetchAuthSession'] rather than jest.Mock. If createMockAmplifyContext returned a type where fetchAuthSession/getTokens/clearCredentials are jest.Mock (e.g. an intersection like AmplifyContext & { fetchAuthSession: jest.Mock; getTokens: jest.Mock; ... }), the casts disappear. A small convenience helper such as withTokens(ctx, accessToken) could also collapse the repeated mockResolvedValue({ tokens: ... }) setup. Not blocking — just a chance to reduce the boilerplate this migration introduces.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — this is a good ergonomic improvement and I agree the as jest.Mock casts are noisy. I've deferred it from this PR for now, for a couple of reasons:

  1. Scope/risk — this PR is the B-auth split of v6 isolation improvements. #14786 and is meant to be a mechanical context migration plus the regression fix above. Changing the return type of createMockAmplifyContext (e.g. to AmplifyContext & { fetchAuthSession: jest.Mock; getTokens: jest.Mock; clearCredentials: jest.Mock }) touches the shared test util that ~28 call sites depend on, and I'd rather not fold a broad test-ergonomics refactor into the same PR as a behavioral fix.
  2. Consistency across splits — the same createMockAmplifyContext util is duplicated in the other B-splits (storage/analytics/notifications each get their own copy per the split plan). I'd prefer to make the typing change once, consistently, rather than diverge auth's copy here.

Happy to do it as a fast follow-up — either a tiny standalone PR against this util, or I can fold it in if you'd prefer it land together. Let me know your preference and I'll take care of it. The withTokens(ctx, accessToken) helper idea is nice too; I'll include that in the same follow-up.

bobbor added 2 commits July 6, 2026 12:26
- Restore USER_AUTH branch in signUpHelpers auto-sign-in: route directly
  to signInWithUserAuth(getGlobalContext(), input) instead of signIn(),
  which called resetAutoSignIn() and dropped the primed autoSignInStore
  session (regression). Re-add the dropped session assertion in
  autoSignIn.test.ts and correct autoSignInUserConfirmed.test.ts to
  assert the restored behavior.
- Extract duplicated server context resolution into resolveServerContext
  shared util, used by server/getCurrentUser and server/fetchUserAttributes.
- Add clearGlobalContext() cleanup in afterAll across test files that set
  a global context; make the Cognito ASF suite self-contained instead of
  relying on cross-describe context leakage.
Move @aws-amplify/core/internals/utils import before relative src imports
to satisfy eslint import/order.
macos-latest runner's Xcode no longer ships the iPhone 16 simulator by
default; target iPhone 17 so the xcodebuild test destination resolves.
@bobbor
bobbor requested a review from a team as a code owner July 6, 2026 13:31
}

export async function assertUserNotAuthenticated() {
export async function assertUserNotAuthenticated(ctx: AmplifyContext) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[major] The ctx threading added here is incomplete further down the call chain. getSignInResult (line 576 in this file), which every signIn variant invokes for challenge-to-output mapping, still reads Amplify.getConfig().Auth?.Cognito directly and has no ctx parameter:

export async function getSignInResult(params: { ... }) {
  const authConfig = Amplify.getConfig().Auth?.Cognito; // singleton, not ctx

The concrete gap: a caller that passes signIn(customCtx, input) with a custom userPoolEndpoint will have their InitiateAuth call routed through the custom endpoint (via signInWithSRP(ctx, input) etc.), but if the flow reaches an MFA_SETUP challenge, the associateSoftwareToken call inside getSignInResult uses the singleton endpoint. Both calls happen in the same sign-in flow and may hit different endpoints.

The fix is to add ctx: AmplifyContext to getSignInResult's parameter object and thread it from each signIn variant. If this is deferred to a follow-up split, it is worth tracking explicitly so callers of the fn(ctx, input) overload are not silently getting mixed-context behavior.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed in 0c91982. You were right — getSignInResult was reading the singleton config, so a custom-endpoint ctx would route InitiateAuth correctly but the MFA_SETUP/associateSoftwareToken path through getSignInResult would hit the singleton endpoint.

Threaded ctx: AmplifyContext as the first param into getSignInResult and switched it to ctx.resourcesConfig.Auth?.Cognito. All 6 callers pass ctx (signInWithSRP/UserAuth/CustomAuth/CustomSRPAuth/UserPassword, confirmSignIn), and the internal WEB_AUTHN recursion (getSignInResult(ctx, result)) plus handleWebAuthnSignInResult were updated too — handleWebAuthnSignInResult now takes ctx as well and uses it for both its authConfig and dispatchSignedInHubEvent(ctx), so the whole challenge-mapping path is single-context now. No deferral needed.

): Promise<void>;
export async function signOut(...args: any[]): Promise<void> {
const [ctx, input] = resolveCtxArgs<[SignOutInput | undefined]>(args);
const cognitoConfig = ctx.resourcesConfig.Auth?.Cognito;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[major] ctx.resourcesConfig is used here for Cognito config, but the credentials and token cleanup later in this function still goes through module-level singletons. Specifically, in the non-OAuth branch:

tokenOrchestrator.clearTokens(); // singleton token store
await clearCredentials();        // clearCredentials imported from @aws-amplify/core, not ctx.clearCredentials()

AmplifyContext exposes ctx.clearCredentials() for exactly this case. Calling the singleton clearCredentials() in a multi-context scenario (which the (ctx, input?) overload is intended for) clears the global Identity pool credential cache, not the per-request one. At minimum, clearCredentials() should be replaced with ctx.clearCredentials(). Whether tokenOrchestrator also needs to be context-scoped depends on this migration phase, but the gap should be explicit if it is a known deferral.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0c91982. Replaced the singleton await clearCredentials() with await ctx.clearCredentials() in the non-OAuth branch and removed the now-unused clearCredentials import from @aws-amplify/core, so per-request credential state is cleared in the (ctx, input?) scenario.

On tokenOrchestrator.clearTokens() — I've left it as the module singleton for now, matching the reference v7-poc which also doesn't context-scope the token orchestrator in this phase. Flagging it explicitly as a known deferral: token-store context-scoping is a broader change beyond this B-auth split.

signInInput?.options?.authFlowType === 'USER_AUTH'
? await signInWithUserAuth(signInInput)
? await signInWithUserAuth(getGlobalContext(), signInInput)
: await signIn(signInInput);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor] The two branches of handleAutoSignInWithCodeOrUserConfirmed pass context inconsistently:

  • USER_AUTH path: await signInWithUserAuth(getGlobalContext(), signInInput) -- context passed explicitly
  • all other paths (this line): await signIn(signInInput) -- context resolved internally via resolveCtxArgs

Both reach getGlobalContext() at runtime, so there is no functional difference. But the asymmetry is surprising to a reader and looks like an accidental omission. Aligning to await signIn(getGlobalContext(), signInInput) (or a short comment explaining the implicit resolution) would remove the ambiguity.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0c91982. Aligned the else branch to await signIn(getGlobalContext(), signInInput) so both branches pass context explicitly. No functional change (as you noted, both resolve to the global context), just removes the surprising asymmetry.

* Resolves a server-side argument that may be either the new {@link AmplifyContext}
* or a legacy {@link AmplifyServer.ContextSpec}, into a concrete `AmplifyContext`.
*/
export const resolveServerContext = (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor] The duck-typing discriminator ('resourcesConfig' in ctxOrContextSpec) is the single point of backward compatibility between the new AmplifyContext path and the legacy ContextSpec path, but there are no dedicated unit tests for it.

Both branches are exercised only indirectly through server/getCurrentUser and server/fetchUserAttributes. A small focused test for resolveServerContext itself -- one call with a mock AmplifyContext (has resourcesConfig) and one with a mock ContextSpec (does not) -- would protect the discriminator independently, so a future change to either type fails here rather than silently in a higher-level test.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 0c91982: __tests__/providers/cognito/apis/server/resolveServerContext.test.ts. Two focused cases — one passing a branded AmplifyContext (asserts it's returned as-is and getAmplifyServerContext is not called), and one passing a legacy ContextSpec (asserts it resolves via getAmplifyServerContext(spec).amplify). So the discriminator is now protected independently of the higher-level server API tests.

? ctxOrContextSpec
: getAmplifyServerContext(ctxOrContextSpec).amplify;

// The `'resourcesConfig' in x` duck-type does not narrow the union to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] This three-line block restates the TypeScript limitation in more words than the cast it documents. A single line captures the same information:

// `'resourcesConfig' in x` doesn't narrow the union; AmplifyClass satisfies AmplifyContext structurally.
return ctx as AmplifyContext;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 0c91982 — collapsed to a single line: // 'resourcesConfig' in x doesn't narrow the union; AmplifyClass satisfies AmplifyContext structurally.

- Thread ctx:AmplifyContext through getSignInResult and
  handleWebAuthnSignInResult (incl. WEB_AUTHN recursion) so the
  MFA_SETUP/TOTP associateSoftwareToken call uses the same context as
  the rest of the sign-in flow instead of the global singleton config.
  Updated all 6 callers to pass ctx.
- signOut: use ctx.clearCredentials() instead of the singleton in the
  non-OAuth branch so per-request credential state is cleared.
- signUpHelpers: pass getGlobalContext() explicitly in the non-USER_AUTH
  auto-sign-in branch for symmetry with the USER_AUTH branch.
- Add focused unit test for resolveServerContext covering both the
  AmplifyContext and legacy ContextSpec branches.
- Collapse verbose comment in resolveServerContext to one line.
@bobbor
bobbor merged commit 1390ec7 into feat/bobbor/v6-context Jul 7, 2026
161 of 165 checks passed
@bobbor
bobbor deleted the feat/b-auth-context branch July 7, 2026 10:02
bobbor added a commit that referenced this pull request Jul 7, 2026
* feat(auth): migrate auth APIs to AmplifyContext (B-auth split)

- Add AmplifyContext overloads to all public auth APIs (signIn, signUp,
  signOut, getCurrentUser, fetchUserAttributes, confirmSignIn, etc.)
- Public APIs use resolveCtxArgs with getGlobalContext() fallback
- Server wrappers (server/getCurrentUser, server/fetchUserAttributes)
  take AmplifyContext explicitly — no global fallback
- Internal signIn variants take (ctx, input) directly
- Utilities (assertUserNotAuthenticated, dispatchSignedInHubEvent) accept ctx
- Replace Amplify.getConfig() with ctx.resourcesConfig throughout
- Replace AmplifyClassV6 with AmplifyContext in internal APIs
- Add createMockAmplifyContext test utility
- Update affected test files to use mock context

* fix: use resolveCtxArgs<[]> for no-input overloads

resolveCtxArgs generic constraint requires T extends unknown[].
undefined does not satisfy this - use empty tuple [] instead.

* fix: use ctx.fetchAuthSession() instead of singleton fetchAuthSession()

The fetchAuthSession helper from core/internals/utils expects AmplifyClass,
not AmplifyContext. Use the context's own fetchAuthSession method directly.

* fix: server wrappers accept both AmplifyContext and ContextSpec

Maintain backward compatibility with adapter-nextjs which still uses
runWithAmplifyServerContext + ContextSpec pattern. Server wrappers now
detect whether they received an AmplifyContext or ContextSpec and
resolve accordingly.

* fix: resolve lint and formatting issues

- Remove unused Amplify imports from test files
- Fix prettier formatting (line length, indentation)

* fix: remove tsconfig.tsbuildinfo build artifact

* fix: update auth tests to use AmplifyContext directly

Migrate test mocking from Amplify.getConfig() singleton to passing
mockCtx directly via createMockAmplifyContext(). This aligns tests
with the new resolveCtxArgs pattern where APIs accept an optional
AmplifyContext as their first argument.

- Remove jest.mock('@aws-amplify/core') in favor of direct ctx passing
- Replace fetchAuthSession singleton mock with ctx.fetchAuthSession
- Use customCtx for endpoint override tests
- Fix autoSignInUserConfirmed to match updated signUpHelpers routing
- Add Amplify.configure() for tests that reach getSignInResult (still
  uses singleton internally)

* fix(auth): address PR review comments

- Restore USER_AUTH branch in signUpHelpers auto-sign-in: route directly
  to signInWithUserAuth(getGlobalContext(), input) instead of signIn(),
  which called resetAutoSignIn() and dropped the primed autoSignInStore
  session (regression). Re-add the dropped session assertion in
  autoSignIn.test.ts and correct autoSignInUserConfirmed.test.ts to
  assert the restored behavior.
- Extract duplicated server context resolution into resolveServerContext
  shared util, used by server/getCurrentUser and server/fetchUserAttributes.
- Add clearGlobalContext() cleanup in afterAll across test files that set
  a global context; make the Cognito ASF suite self-contained instead of
  relying on cross-describe context leakage.

* fix(auth): correct import order in autoSignInUserConfirmed test

Move @aws-amplify/core/internals/utils import before relative src imports
to satisfy eslint import/order.

* test(rtn-passkeys): use iPhone 17 simulator for iOS unit tests

macos-latest runner's Xcode no longer ships the iPhone 16 simulator by
default; target iPhone 17 so the xcodebuild test destination resolves.

* fix(auth): address review feedback on context threading

- Thread ctx:AmplifyContext through getSignInResult and
  handleWebAuthnSignInResult (incl. WEB_AUTHN recursion) so the
  MFA_SETUP/TOTP associateSoftwareToken call uses the same context as
  the rest of the sign-in flow instead of the global singleton config.
  Updated all 6 callers to pass ctx.
- signOut: use ctx.clearCredentials() instead of the singleton in the
  non-OAuth branch so per-request credential state is cleared.
- signUpHelpers: pass getGlobalContext() explicitly in the non-USER_AUTH
  auto-sign-in branch for symmetry with the USER_AUTH branch.
- Add focused unit test for resolveServerContext covering both the
  AmplifyContext and legacy ContextSpec branches.
- Collapse verbose comment in resolveServerContext to one line.
bobbor added a commit that referenced this pull request Aug 3, 2026
* feat(auth): migrate auth APIs to AmplifyContext (B-auth split)

- Add AmplifyContext overloads to all public auth APIs (signIn, signUp,
  signOut, getCurrentUser, fetchUserAttributes, confirmSignIn, etc.)
- Public APIs use resolveCtxArgs with getGlobalContext() fallback
- Server wrappers (server/getCurrentUser, server/fetchUserAttributes)
  take AmplifyContext explicitly — no global fallback
- Internal signIn variants take (ctx, input) directly
- Utilities (assertUserNotAuthenticated, dispatchSignedInHubEvent) accept ctx
- Replace Amplify.getConfig() with ctx.resourcesConfig throughout
- Replace AmplifyClassV6 with AmplifyContext in internal APIs
- Add createMockAmplifyContext test utility
- Update affected test files to use mock context

* fix: use resolveCtxArgs<[]> for no-input overloads

resolveCtxArgs generic constraint requires T extends unknown[].
undefined does not satisfy this - use empty tuple [] instead.

* fix: use ctx.fetchAuthSession() instead of singleton fetchAuthSession()

The fetchAuthSession helper from core/internals/utils expects AmplifyClass,
not AmplifyContext. Use the context's own fetchAuthSession method directly.

* fix: server wrappers accept both AmplifyContext and ContextSpec

Maintain backward compatibility with adapter-nextjs which still uses
runWithAmplifyServerContext + ContextSpec pattern. Server wrappers now
detect whether they received an AmplifyContext or ContextSpec and
resolve accordingly.

* fix: resolve lint and formatting issues

- Remove unused Amplify imports from test files
- Fix prettier formatting (line length, indentation)

* fix: remove tsconfig.tsbuildinfo build artifact

* fix: update auth tests to use AmplifyContext directly

Migrate test mocking from Amplify.getConfig() singleton to passing
mockCtx directly via createMockAmplifyContext(). This aligns tests
with the new resolveCtxArgs pattern where APIs accept an optional
AmplifyContext as their first argument.

- Remove jest.mock('@aws-amplify/core') in favor of direct ctx passing
- Replace fetchAuthSession singleton mock with ctx.fetchAuthSession
- Use customCtx for endpoint override tests
- Fix autoSignInUserConfirmed to match updated signUpHelpers routing
- Add Amplify.configure() for tests that reach getSignInResult (still
  uses singleton internally)

* fix(auth): address PR review comments

- Restore USER_AUTH branch in signUpHelpers auto-sign-in: route directly
  to signInWithUserAuth(getGlobalContext(), input) instead of signIn(),
  which called resetAutoSignIn() and dropped the primed autoSignInStore
  session (regression). Re-add the dropped session assertion in
  autoSignIn.test.ts and correct autoSignInUserConfirmed.test.ts to
  assert the restored behavior.
- Extract duplicated server context resolution into resolveServerContext
  shared util, used by server/getCurrentUser and server/fetchUserAttributes.
- Add clearGlobalContext() cleanup in afterAll across test files that set
  a global context; make the Cognito ASF suite self-contained instead of
  relying on cross-describe context leakage.

* fix(auth): correct import order in autoSignInUserConfirmed test

Move @aws-amplify/core/internals/utils import before relative src imports
to satisfy eslint import/order.

* test(rtn-passkeys): use iPhone 17 simulator for iOS unit tests

macos-latest runner's Xcode no longer ships the iPhone 16 simulator by
default; target iPhone 17 so the xcodebuild test destination resolves.

* fix(auth): address review feedback on context threading

- Thread ctx:AmplifyContext through getSignInResult and
  handleWebAuthnSignInResult (incl. WEB_AUTHN recursion) so the
  MFA_SETUP/TOTP associateSoftwareToken call uses the same context as
  the rest of the sign-in flow instead of the global singleton config.
  Updated all 6 callers to pass ctx.
- signOut: use ctx.clearCredentials() instead of the singleton in the
  non-OAuth branch so per-request credential state is cleared.
- signUpHelpers: pass getGlobalContext() explicitly in the non-USER_AUTH
  auto-sign-in branch for symmetry with the USER_AUTH branch.
- Add focused unit test for resolveServerContext covering both the
  AmplifyContext and legacy ContextSpec branches.
- Collapse verbose comment in resolveServerContext to one line.
bobbor added a commit that referenced this pull request Aug 3, 2026
Thread AmplifyContext explicitly through the storage package instead of
relying on the global Amplify singleton, mirroring the landed auth
migration (#14836).

- Public S3 APIs (copy, downloadData, getProperties, getUrl, list,
  remove, uploadData) gain (ctx, input) overloads with a global
  fallback via resolveCtxArgs
- Internal workers, resolveS3ConfigAndInput, and access-grant internals
  take ctx: AmplifyContext; config via ctx.resourcesConfig and auth via
  ctx.fetchAuthSession
- Server wrappers accept AmplifyContext | AmplifyServer.ContextSpec via
  new resolveServerContext, preserving adapter-nextjs compatibility
- Tests migrated to a branded mock AmplifyContext (createMockAmplifyContext)

Excludes the endpoint-provider feature (depends on unlanded core
Storage types) and does not delete server impls (adapter-nextjs split
not yet landed).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants